from typing import Generator, Optional
from fastapi import Depends, HTTPException, status
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from sqlalchemy.orm import Session

from app.core.database import SessionLocal  # 直接导入SessionLocal
from app.models.user import User
from app.services.auth_service import AuthService
from app.core.logging import get_logger

logger = get_logger(__name__)

# 创建HTTPBearer安全方案，auto_error=False允许可选认证
security = HTTPBearer(auto_error=False)


def get_db() -> Generator[Session, None, None]:
    """ 获取数据库会话 """
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()


async def get_current_user(
    credentials: HTTPAuthorizationCredentials = Depends(security),
    db: Session = Depends(get_db)
) -> User:
    """ 获取当前用户 """
    credentials_exception = HTTPException(
        status_code=status.HTTP_401_UNAUTHORIZED,
        detail="无法验证凭据",
        headers={"WWW-Authenticate": "Bearer"},
    )
    
    # 检查是否提供了认证凭据
    if not credentials:
        raise credentials_exception
    
    try:
        auth_service = AuthService(db)
        token_data = auth_service.verify_token(credentials.credentials)
        
        if token_data is None:
            raise credentials_exception
        
        user = auth_service.user_service.get_by_id(token_data.user_id)
        if user is None:
            raise credentials_exception
        
        return user
    except HTTPException:
        # 重新抛出HTTP异常
        raise
    except Exception as e:
        logger.error(f"认证错误: {str(e)}", exc_info=True)  # 添加结构化错误日志
        raise credentials_exception


async def get_current_active_user(
    current_user: User = Depends(get_current_user)
) -> User:
    """ 获取当前活跃用户 """
    if not current_user.is_active:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="用户未激活"
        )
    return current_user


async def get_current_superuser(
    current_user: User = Depends(get_current_active_user)
) -> User:
    """获取当前超级用户"""
    if not current_user.is_superuser:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="需要超级用户权限"
        )
    return current_user


async def get_optional_current_user(
    db: Session = Depends(get_db),
    credentials: Optional[HTTPAuthorizationCredentials] = Depends(
        HTTPBearer(auto_error=False)
    )
) -> Optional[User]:
    """可选的当前用户 - 不会抛出异常如果没有认证"""
    if not credentials:
        return None
    
    try:
        auth_service = AuthService(db)
        token_data = auth_service.verify_token(credentials.credentials)
        if token_data:
            return auth_service.user_service.get_by_id(token_data.user_id)
    except Exception as e:
        logger.debug(f"可选认证失败: {str(e)}")  # 添加调试日志
        pass
    
    return None